package day07;

/**
 * @description: 数组工具类的创建
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

public class ArrayUtilsDemo {
    public static void main(String[] args) {
        // 工具类中的方法全都是静态方法，可以直接类名点调用，无需创建对象
    }
}

class ArrayUtils {

    /**
     * 该方法会在控制台循环打印int数组的元素，可以接受null和空数组输入。
     * @since 9:44
     * @param arr 需要被遍历输出的int类型数组
     * @author wuguidong@cskaoyan.onaliyun.com
     */
    public static void traverse(int[] arr) {
        // 应该单独判断null,单独处理
        if (arr == null) {
            // null数组
            System.out.println("您输入的数组是null数组,请重新输入!");
            return;
        }
        // 程序运行到这里,数组肯定不是null,避免了空指针异常
        if (arr.length == 0) {
            // 长度为0,直接给出提示结束方法即可
            System.out.println("[]");
            System.out.println("您输入的数组长度为0!请重新输入!");
            // 用return结束方法,可以少写一个else
            return;
        }
        // 代码执行到这里,数组长度一定不为0
        System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + ", ");
        }
        System.out.println("\b\b]");
    }


    /**
     * 获取int数组中的最大值
     *      利用包装类型，使得该方法可以接受长度为0或者null数组的输入
     * @since 9:50
     * @param arr 被求最大值的int数组
     * @return java.lang.Integer
     * @author wuguidong@cskaoyan.onaliyun.com
     */
    public static Integer getMaxValue(int[] arr) {
        if (arr == null || arr.length == 0) {
            System.out.println("错误参数，数组是null或者长度为0！");
            return null;
        }
        int max = arr[0];
        // 遍历数组,逐一比较
        for (int element : arr) {
            // 如果元素更大,就成为新的最大值
            if (element > max) {
                max = element;
            }
        }
        return max;
    }

    /**
     * 获取int数组中的最小值
     *      利用包装类型，使得该方法可以接受长度为0或者null数组的输入
     * @since 9:50
     * @param arr 被求最小值的int数组
     * @return java.lang.Integer
     * @author wuguidong@cskaoyan.onaliyun.com
     */
    public static Integer getMinValue(int[] arr) {
        if (arr == null || arr.length == 0) {
            System.out.println("错误参数，数组是null或者长度为0！");
            return null;
        }
        int min = arr[0];
        // 遍历数组,逐一比较
        for (int element : arr) {
            // 如果元素更小,就成为新的最小值
            if (element < min) {
                min = element;
            }
        }
        return min;
    }

    /**
     * 在原有数组的基础上，将它的元素逆置
     * @since 10:01
     * @param arr 被逆置的数组
     * @author wuguidong@cskaoyan.onaliyun.com
     */
    public static void reserve(int[] arr) {
        /*
            这个遍历交换的过程,进行数组的一半就可以了
            如果遍历完整个数组,那就交换了两次,又换回来了
         */
        for (int i = 0; i < arr.length / 2; i++) {
            // 核心arr[i] <---> arr[arr.length-i-1]
            int temp = arr[i];
            arr[i] = arr[arr.length - i - 1];
            arr[arr.length - i - 1] = temp;
        }
    }


    /**
     * 在目标数组中查找目标元素,如果找到了,就立刻返回它的下标
     *      即第一次查找到该元素的下标
     *      当然也完全可能找不到,返回-1表示目标元素不存在
     * @since 11:46
     * @param arr 被查找元素的数组
     * @param target 目标元素
     * @return int 找到目标元素的下标
     * @author wuguidong@cskaoyan.onaliyun.com
     */
    public static int getFirstTargetElementIndex(String[] arr, String target) {
        // 预先定义一个返回结果的下标
        int resultIndex = -1;
        for (int i = 0; i < arr.length; i++) {
            // 避免空指针异常,最简单的方法就是if判断
            if (arr[i] == null) {
                // 直接跳过循环,避免空指针异常
                continue;
            }
            if (arr[i].equals(target)) {
                // 找到目标元素,i就是目标下标
                resultIndex = i;
                return resultIndex;
            }
        }
        /*
            代码运行到这里,说明没有找到目标元素,那返回下标返回-1
            直接return -1;是没有大问题的,但是有小问题,这就牵扯一个写代码的规范
            像-1,"hello"这种字面值常量,它是没有名字的,这种值如果刚写完,代码是可以读懂的.
            但时间比较久了,没有名字就不知道它的用途了
            这种直接写在代码中字面值,叫做"魔法值",魔法值在代码中最好不要写,写魔法值对代码块可读性不好
         */
        return resultIndex;
    }

    /**
     * 在目标数组中查找目标元素,直到遍历完整个数组
     *      即该方法返回最后一次查找到该元素的下标
     *      当然也完全可能找不到,返回-1表示目标元素不存在
     * @since 11:46
     * @param arr 被查找元素的数组
     * @param target 目标元素
     * @return int 找到目标元素的下标
     * @author wuguidong@cskaoyan.onaliyun.com
     */
    public static int getLastTargetElementIndex(String[] arr, String target) {
        // 预先定义一个返回结果的下标
        int resultIndex = -1;
        // 倒着遍历数组,找最后一个目标元素
        for (int i = arr.length - 1; i >= 0; i--) {
            // 避免空指针异常,最简单的方法就是if判断
            if (arr[i] == null) {
                // 直接跳过循环,避免空指针异常
                continue;
            }
            if (arr[i].equals(target)) {
                // 找到目标元素,i就是目标下标
                resultIndex = i;
                return resultIndex;
            }
        }
        return resultIndex;
    }


}
